﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Reflection;
using System.Text;

namespace ZOVNP.WinView
{
    /// <summary> Парсер командной строки </summary>
    /// <remarks> Класс разбирает ключи командной строки </remarks>
    [Description("Парсер командной строки")]
    public class CommandLineParser
    {

        #region Ключи командной строки

        /// <summary> Ключ командной строки для указания имени сервера </summary>
        private const string CMD_LINE_DATASOURCE1 = "/SERVER=";
        /// <summary> Ключ командной строки для указания имени сервера </summary>
        private const string CMD_LINE_DATASOURCE2 = "/DATASOURCE=";
        /// <summary> Ключ командной строки для указания БД </summary>
        private const string CMD_LINE_BASE1 = "/BASE=";
        /// <summary> Ключ командной строки для указания БД </summary>
        private const string CMD_LINE_BASE2 = "/DATABASE=";
        /// <summary> Ключ командной строки для указания БД </summary>
        private const string CMD_LINE_BASE3 = "/DB=";
        /// <summary> Ключ командной строки для указания БД </summary>
        private const string CMD_LINE_BASE4 = "/INITIALCATALOG=";
        /// <summary> Ключ командной строки для имени пользователя </summary>
        private const string CMD_LINE_LOGIN1 = "/LOGIN=";
        /// <summary> Ключ командной строки для имени пользователя </summary>
        private const string CMD_LINE_LOGIN2 = "/USER=";
        /// <summary> Ключ командной строки для имени пользователя </summary>
        private const string CMD_LINE_LOGIN3 = "/USERID=";
        /// <summary> Ключ командной строки для Windows authentication </summary>
        private const string CMD_LINE_INTEGRATEDSECURITY1 = "/INTEGRATEDSECURITY=";
        /// <summary> Ключ командной строки для Windows authentication </summary>
        private const string CMD_LINE_INTEGRATEDSECURITY2 = "/SSPI=";

        #endregion

        /// <summary> Состояние объекта </summary>
        private CommandLineParserStates m_state;
        /// <summary> Класс логина </summary>
        private Login m_login;

        /// <summary> Конструктор </summary>
        /// <param name="args"> параметры командной строки </param>
        /// <param name="login"> логин </param>
        internal CommandLineParser(string[] args, Login login)
        {
            m_login = login;
            for (int j = 0; j < args.Length; j++)
            {
                // переводим в верхний регистр
                string param = args[j].ToUpper();
                // ищем вхождения ключей командной строки
                if (param.IndexOf(CMD_LINE_DATASOURCE1) == 0)
                    // задаем имя сервера
                    this.DataSource = param.Replace(CMD_LINE_DATASOURCE1, null);
                else if (param.IndexOf(CMD_LINE_DATASOURCE2) == 0)
                    // задаем имя сервера
                    this.DataSource = param.Replace(CMD_LINE_DATASOURCE2, null);
                else if (param.IndexOf(CMD_LINE_BASE1) == 0)
                    // задаем имя БД
                    this.InitialCatalog = param.Replace(CMD_LINE_BASE1, null);
                else if (param.IndexOf(CMD_LINE_BASE2) == 0)
                    // задаем имя БД
                    this.InitialCatalog = param.Replace(CMD_LINE_BASE2, null);
                else if (param.IndexOf(CMD_LINE_BASE3) == 0)
                    // задаем имя БД
                    this.InitialCatalog = param.Replace(CMD_LINE_BASE3, null);
                else if (param.IndexOf(CMD_LINE_BASE4) == 0)
                    // задаем имя БД
                    this.InitialCatalog = param.Replace(CMD_LINE_BASE4, null);
                else if (param.IndexOf(CMD_LINE_LOGIN1) == 0)
                    // задаем имя пользователя
                    this.UserID = param.Replace(CMD_LINE_LOGIN1, null);
                else if (param.IndexOf(CMD_LINE_LOGIN2) == 0)
                    // задаем имя пользователя
                    this.UserID = param.Replace(CMD_LINE_LOGIN2, null);
                else if (param.IndexOf(CMD_LINE_LOGIN3) == 0)
                    // задаем имя пользователя
                    this.UserID = param.Replace(CMD_LINE_LOGIN3, null);
                else if (param.IndexOf(CMD_LINE_INTEGRATEDSECURITY1) == 0)
                    // задаем Windows authentication
                    this.IntegratedSecurity = param.Replace(CMD_LINE_INTEGRATEDSECURITY1, null);
                else if (param.IndexOf(CMD_LINE_INTEGRATEDSECURITY2) == 0)
                    // задаем Windows authentication
                    this.IntegratedSecurity = param.Replace(CMD_LINE_INTEGRATEDSECURITY2, null);
                else
                    // беда какая-то
                    throw new ArgumentException("Неверный параметр командной строки", param);
            }
        }
        /// <summary> Получить (установить) состояние объекта </summary>
        /// <value> добавляемое состояние </value>
        private CommandLineParserStates State
        {
            get { return (m_state); }
            set
            {
                if ((m_state & value) == 0)
                    m_state |= value;
                else
                {
                    FieldInfo info = typeof(CommandLineParserStates).GetField((m_state & value).ToString());
                    DescriptionAttribute da = (DescriptionAttribute)Attribute.GetCustomAttribute(info, typeof(DescriptionAttribute));
                    throw new ArgumentException("Повтор параметра командной строки", da != null ? da.Description : "");
                }
            }
        }
        /// <summary> Установка имени сервера </summary>
        /// <value> имя сервера </value>
        private string DataSource
        {
            set
            {
                if (!String.IsNullOrEmpty(value))
                {
                    this.State = CommandLineParserStates.DataSource;
                    m_login.CurrentDataSource = value;
                    //m_login.AddDataSource(value);
                }
                else
                    throw new ArgumentException("Неверный параметр командной строки", "Имя сервера");
            }
        }
        /// <summary> Установить имя БД </summary>
        /// <value> имя БД </value>
        private string InitialCatalog
        {
            set
            {
                if (!String.IsNullOrEmpty(value))
                {
                    this.State = CommandLineParserStates.InitialCatalog;
                    m_login.CurrentInitialCatalog = value;
                    //m_login.InitialCatalog.Add(value);
                }
                else
                    throw new ArgumentException("Неверный параметр командной строки", "Имя БД");
            }
        }
        /// <summary> Установить имя пользователя </summary>
        /// <value> имя пользователя </value>
        private string UserID
        {
            set
            {
                if (!String.IsNullOrEmpty(value))
                {
                    this.State = CommandLineParserStates.UserID;
                    m_login.UserID = value;
                }
                else
                    throw new ArgumentException("Неверный параметр командной строки", "Имя пользователя(логин)");
            }
        }
        /// <summary> Установить Windows аутентификацию </summary>
        /// <value>  </value>
        private string IntegratedSecurity { set { m_login.IntegratedSecurity = Convert.ToBoolean(value); } }
    }
    /// <summary> Состояния парсера командной строки </summary>
    [FlagsAttribute]
    internal enum CommandLineParserStates
    {
        /// <summary> Пусто (не определено) </summary>
        [Description("Пусто (не определено)")]
        None = 0,
        /// <summary> Параметр для установки сервера </summary>
        [Description("Параметр для установки сервера")]
        DataSource = 1,
        /// <summary> Параметр для установки БД </summary>
        [Description("Параметр для установки БД")]
        InitialCatalog = 2,
        /// <summary> Параметр для установки имени пользователя </summary>
        [Description("Параметр для установки имени пользователя")]
        UserID = 4
    }
}
